package com.informatics.polymer.server.propertysearch;

import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import nu.xom.Document;
import nu.xom.Element;

import org.apache.commons.io.FileUtils;
import org.restlet.Context;
import org.restlet.data.Form;
import org.restlet.data.MediaType;
import org.restlet.data.Request;
import org.restlet.data.Response;
import org.restlet.data.Status;
import org.restlet.resource.Representation;
import org.restlet.resource.Resource;
import org.restlet.resource.ResourceException;
import org.restlet.resource.StringRepresentation;
import org.restlet.resource.Variant;

import com.informatics.polymer.server.database.DatabaseInteraction;

/**
 * Restlet to extract all repeat units in the derby database that match the
 * property search criteria.
 * 
 * @author ed
 * @version 1.0
 */
public class PropertySearchResource extends Resource {
	/**
	 * All properties selected with max and minimum ranges.
	 */
	private String propertiesWithRanges;

	/**
	 * 
	 * @return String representation of all the property data with limits.
	 */
	private String getPropertyInformation() {
		return propertiesWithRanges;
	}
	/**
	 * 
	 * @param properties - String representation of all property information entered.
	 */
	private void setPropertyString(String properties){
		propertiesWithRanges = properties;
	}
	/**
	 * Method allows forms to be posted to restlet.
	 */
	@Override
	public boolean allowPost() {
		return true;
	}

	@Override
	public void init(Context context, Request request, Response response) {
		super.init(context, request, response);
		getVariants().add(new Variant(MediaType.TEXT_PLAIN));
	}
	/**
	 * Method deals with the form posted to the restlet.
	 */
	@SuppressWarnings("deprecation")
	@Override
	public void post(Representation entity){
		Form form = new Form(entity); 
		setPropertyString(form.getValues("propertyInfo"));
		//Split on ; and , into arraylist of RepeatUnitProperty
		String[] separateProperties = getPropertyInformation().split(";");
		ArrayList<RepeatUnitProperty> repeatUnitProperties = new ArrayList<RepeatUnitProperty>();
		for(int i=0;i<separateProperties.length;i++){
			String[] separateComponents = separateProperties[i].split(",");
			RepeatUnitProperty repeatUnitProperty = new RepeatUnitProperty(separateComponents[0],Double.parseDouble(separateComponents[1]),Double.parseDouble(separateComponents[2]));
			repeatUnitProperties.add(repeatUnitProperty);
		}
		StringBuffer sb = new StringBuffer();
		DatabaseInteraction databaseInteraction = new DatabaseInteraction();
		try {
			databaseInteraction.init();
			List<com.informatics.polymer.server.database.RepeatUnit> resu = databaseInteraction
					.propertySearch(repeatUnitProperties);
			Element root = new Element("RepeatUnits");
			for (com.informatics.polymer.server.database.RepeatUnit ru : resu) {
				double[] descriptors = ru.getDescriptors();
				Element repeatUnit = new Element("RepeatUnit");
				Element id = new Element("Id");
				id.appendChild(ru.getId());
				Element ruPictureURL = new Element("URL");
				ruPictureURL.appendChild("http://localhost:8080/RepeatUnitPictures/"+ru.getId().trim()+".png");
				Element smilesString = new Element("Smiles");
				smilesString.appendChild(ru.getSmilesString());
				repeatUnit.appendChild(id);
				repeatUnit.appendChild(ruPictureURL);
				repeatUnit.appendChild(smilesString);
				// Add descriptor elements.
				Element alogP = new Element("ALOGP");
				alogP.appendChild(Double.toString(descriptors[0]));
				Element alogp2 = new Element("AlogP2");
				alogp2.appendChild(Double.toString(descriptors[1]));
				Element amr = new Element("AMR");
				amr.appendChild(Double.toString(descriptors[2]));
				Element apol = new Element("APol");
				apol.appendChild(Double.toString(descriptors[3]));
				Element aromaticAtomCount = new Element("AromaticAtomCount");
				aromaticAtomCount.appendChild(Double
						.toString(descriptors[4]));
				Element aromaticBondCount = new Element("AromaticBondCount");
				aromaticBondCount.appendChild(Double
						.toString(descriptors[5]));
				Element atomCount = new Element("AtomCount");
				atomCount.appendChild(Double.toString(descriptors[6]));
				Element bondCount = new Element("BondCount");
				bondCount.appendChild(Double.toString(descriptors[7]));
				Element fragmentComplexity = new Element(
						"FragmentComplexity");
				fragmentComplexity.appendChild(Double
						.toString(descriptors[8]));
				Element hbaCount = new Element("HBACount");
				hbaCount.appendChild(Double.toString(descriptors[9]));
				Element hbdCount = new Element("HBDCount");
				hbdCount.appendChild(Double.toString(descriptors[10]));
				Element kappa1 = new Element("Kappa1");
				kappa1.appendChild(Double.toString(descriptors[11]));
				Element kappa2 = new Element("Kappa2");
				kappa2.appendChild(Double.toString(descriptors[12]));
				Element kappa3 = new Element("Kappa3");
				kappa3.appendChild(Double.toString(descriptors[13]));
				Element ruleOf5 = new Element("LipinskiRuleOf5Failures");
				ruleOf5.appendChild(Double.toString(descriptors[14]));
				Element tpsa = new Element("TPSA");
				tpsa.appendChild(Double.toString(descriptors[15]));
				repeatUnit.appendChild(alogP);
				repeatUnit.appendChild(alogp2);
				repeatUnit.appendChild(amr);
				repeatUnit.appendChild(apol);
				repeatUnit.appendChild(aromaticAtomCount);
				repeatUnit.appendChild(aromaticBondCount);
				repeatUnit.appendChild(atomCount);
				repeatUnit.appendChild(bondCount);
				repeatUnit.appendChild(fragmentComplexity);
				repeatUnit.appendChild(hbaCount);
				repeatUnit.appendChild(hbdCount);
				repeatUnit.appendChild(kappa1);
				repeatUnit.appendChild(kappa2);
				repeatUnit.appendChild(kappa3);
				repeatUnit.appendChild(ruleOf5);
				repeatUnit.appendChild(tpsa);
				root.appendChild(repeatUnit);
				sb.append("\n");
			}
			Document doc = new Document(root);
			String f = "/PropertySearchDump" + ".xml";
			String curDir = new String(System.getProperty("user.dir"));
			File databaseXml = new File(curDir + f);
			// Use apache io
			try {
				FileUtils.writeStringToFile(databaseXml, doc.toXML());
			} catch (IOException e1) {
				e1.printStackTrace();
			}

		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		getResponse().setEntity("Test");

	}
	// Respond to GET
	@Override
	public Representation represent(Variant variant) throws ResourceException {
		Representation resource = null;
		if (!MediaType.TEXT_PLAIN.includes(variant.getMediaType())) {
			throw new ResourceException(Status.CLIENT_ERROR_NOT_ACCEPTABLE);
		} else {
			StringBuffer sb = new StringBuffer();
			resource = new StringRepresentation(sb.toString(),
					MediaType.TEXT_PLAIN);
			return resource;
		}
	}

}
